﻿using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace ClientConclusionListGenerator.FileProcessors
{
    public class ClientDataFileV2Processor : ClientDataFileProcessorBase
    {
        public override bool IsSupport(string input)
        {
            // TODO: more logic check
            return Path.GetExtension(input).ToLower() == ".xlsx";
        }

        public override ClientData Process(string input)
        {
            var client = new ClientData();
            client.Name = Path.GetFileNameWithoutExtension(input).Replace("[对数表]", string.Empty);

            try
            {
                using (var package = new ExcelPackage(new FileInfo(input)))
                {
                    client.MaterialUnpaid = 0d;

                    var book = package.Workbook;

                    if (book.Worksheets.Count <= 2) // simple sheet data
                    {
                        var sheet = book.Worksheets[1];
                        if (sheet.Name == "参数")
                            sheet = book.Worksheets[2];

                        ProcessMaterialTradeDetailSheet(client, sheet);
                    }
                    else // complex sheet data with one or more conclusion sheets
                    {
                        var conclusionSheets = new List<ExcelWorksheet>(5);

                        for (int i = 1; i <= book.Worksheets.Count; i++)
                        {
                            var sheet = book.Worksheets[i];
                            if (IsMaterialTradeConclusionSheet(sheet) && !IsHistorySheet(sheet))
                                conclusionSheets.Add(sheet);
                        }

                        if (conclusionSheets.Count > 0)
                        {
                            foreach (var sheet in conclusionSheets)
                            {
                                ProcessMaterialTradeConclusionSheet(client, sheet);
                            }
                        }
                        else
                        {
                            throw new NotSupportedException("不支持该文件的解释：" + input);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                client.MaterialUnpaid = -999999999; // error value
                SimpleLogger.Log(new string[] { input, ex.ToString() });
            }

            return client;
        }

        /// <summary>
        /// 表格是否已经结算完毕，仅仅作为历史记录保存
        /// </summary>
        /// <param name="sheet"></param>
        /// <returns></returns>
        private bool IsHistorySheet(ExcelWorksheet sheet)
        {
            return sheet.TabColor == System.Drawing.Color.Red 
                || sheet.Protection.IsProtected 
                || sheet.TabColor == System.Drawing.Color.FromArgb(255, 192, 0);
        }


        private void ProcessMaterialTradeConclusionSheet(ClientData client, ExcelWorksheet sheet)
        {
            string contactInfo = sheet.HeaderFooter.OddHeader.LeftAlignedText;

            if (!string.IsNullOrEmpty(contactInfo))
            {
                var info_match = Regex.Match(contactInfo, "联系人[:：](.*?)电话[:：](.*?)地址[:：](.*)");

                if (info_match.Success)
                {
                    client.Phone = info_match.Groups[2].Value.Trim();
                    client.Address = info_match.Groups[3].Value.Trim();
                    client.ContactPerson = info_match.Groups[1].Value.Trim();

                    if (string.IsNullOrEmpty(client.Phone))
                    {
                        SimpleLogger.Log(new String[] { client.Name + " 缺少联系人电话" });
                    }
                }
                else
                {
                    SimpleLogger.Log(new String[] { client.Name + " 匹配联系人信息失败" });
                }
            }
            else
            {
                SimpleLogger.Log(new String[] { client.Name + " 缺少联系人信息" });
            }

            client.MaterialUnpaid += Convert.ToDouble(sheet.Cells[sheet.Dimension.End.Row, 4].Value);
            client.LastTradeDate = DateTime.MinValue;
        }

        private void ProcessMaterialTradeDetailSheet(ClientData client, ExcelWorksheet sheet)
        {
            string contactInfo = sheet.HeaderFooter.OddHeader.LeftAlignedText;

            if (!string.IsNullOrEmpty(contactInfo))
            {
                var info_match = Regex.Match(contactInfo, "联系人[:：](.*?)电话[:：](.*?)地址[:：](.*)");

                if (info_match.Success)
                {
                    client.Phone = info_match.Groups[2].Value.Trim();
                    client.Address = info_match.Groups[3].Value.Trim();
                    client.ContactPerson = info_match.Groups[1].Value.Trim();
                }
            }

            var lastRowIndex = sheet.Dimension.End.Row;
            if (IsTotalRow(sheet, lastRowIndex))
            {
                client.MaterialUnpaid += Convert.ToDouble(sheet.Cells[lastRowIndex, 8].Value);
            }
            else
            {
                SimpleLogger.Log(new string[] { client.Name + " row " + lastRowIndex.ToString() });
                // go through all rows and sum rows'value
                throw new Exception("A sheet without total row cannot be processed at current version");
            }


            try
            {
                string datePart = null;
                string yearPart = null;

                var curRowIndex = lastRowIndex;

                while (curRowIndex >= 1)
                {
                    var curRowFirstCell = sheet.Cells[curRowIndex, 1];
                    curRowIndex--;

                    // get date part
                    if (!curRowFirstCell.Merge && string.IsNullOrEmpty(datePart))
                    {
                        datePart = curRowFirstCell.Text;
                    }


                    // get year part
                    if (!string.IsNullOrEmpty(datePart) && curRowFirstCell.Merge)
                    {
                        if (curRowFirstCell.Text.EndsWith("年"))
                        {
                            yearPart = curRowFirstCell.Text.Replace("年", "");
                            if (datePart.Contains("月份"))
                                datePart = datePart.Replace("月份", "") + "-1";
                            client.LastTradeDate = DateTime.Parse(yearPart + "-" + datePart);
                            break;
                        }
                    }
                }
            }
            catch
            {
                SimpleLogger.Log(new string[] { string.Format("Retriving {0}'s last-trade-date failed", client.Name) });
            }
        }

        private bool IsTotalRow(ExcelWorksheet sheet, int row)
        {
            if (sheet == null)
                return false;

            var cell = sheet.Cells[row, 1];
            if (cell == null)
                return false;

            if (!cell.Merge)
                return false;

            var val = cell.Text;
            if (val == null)
                return false;

            return val.Contains("总欠款")
                || val.Contains("合计")
                || val.Contains("总计");
        }

        private bool IsMaterialTradeConclusionSheet(ExcelWorksheet sheet)
        {
            return sheet.Name.Contains("汇总");
        }
    }
}
